﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using HtmlAgilityPack;
using System.Web;
using System.Threading;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Security.Cryptography;
using System.Reflection;

namespace SF.Base.Core {

	public static class UtilHelper {

		public static string GetMd5(string data) {
			byte[] result = Encoding.Default.GetBytes(data);
			MD5 md5 = new MD5CryptoServiceProvider();
			byte[] output = md5.ComputeHash(result);
			return BitConverter.ToString(output).Replace("-", "");
		}

		public static void Write(this HttpContext hc, string output) {
			try {
				hc.Response.Write(output);
				hc.ApplicationInstance.CompleteRequest();
			}
			catch {
				//do nothing
			}
		}
		public static void Write(this HttpContext hc, int output) {
			try {
				hc.Response.Write(output.ToString());
				hc.ApplicationInstance.CompleteRequest();
			}
			catch {
				//do nothing
			}
		}

		public static void WriteLine(this HttpContext hc, string output) {
			try {
				hc.Response.Write(output);
			}
			catch {
				//do nothing
			}
		}

		public static void End(this HttpContext hc) {
			try {
				hc.ApplicationInstance.CompleteRequest();
			}
			catch {
				//do nothing
			}
		}


		#region Request扩展方法
		public static long GetLong(this HttpRequest req, string key) {
			long def = -9999;
			if (!string.IsNullOrEmpty(req[key])) {
				if (long.TryParse(req[key], out def)) {
					return def;
				}
			}
			return def;
		}
		public static int GetInt(this HttpRequest req, string key) {
			int def = -9999;
			if (!string.IsNullOrEmpty(req[key])) {
				if (int.TryParse(req[key], out def)) {
					return def;
				}
			}
			return def;
		}

		public static int GetInt(this HttpRequest req, string key, int def) {
			int t = def;
			if (!string.IsNullOrEmpty(req[key])) {
				if (int.TryParse(req[key], out t)) {
					return t;
				}
			}
			return def;
		}

		public static string GetStr(this HttpRequest req, string key) {
			if (!string.IsNullOrEmpty(req[key])) {
				return req[key];
			}
			return string.Empty;
		}

		public static string GetStream(this HttpRequest req) {
			StreamReader sr = new StreamReader(req.InputStream);
			if (sr != null) {
				return sr.ReadToEnd();
			}
			return string.Empty;
		}

		public static string GetStr(this HttpRequest req, string key, string def) {
			if (!string.IsNullOrEmpty(req[key])) {
				return req[key];
			}
			return def;
		}

		public static void WriteRetJson(this HttpResponse resp, int code) {
			string msg = ErrorHelper.GetErrorMsg(code);
			resp.WriteRetJson(code, msg);
		}

		public static void WriteRetJson(this HttpResponse resp, int code, string msg) {
			resp.WriteRetJson(code.ToString(), msg);
		}

		public static void WriteRetJson(this HttpResponse resp, string code, string msg) {
			Logger.Detail("{code:" + code + ",msg:\"" + msg + "\"}");
			resp.Write("{code:" + code + ",msg:\"" + msg + "\"}");
			resp.End();
		}

		public static void WriteRetJson(this HttpResponse resp, string code, string msg,string obj) {
			Logger.Detail("{code:" + code + ",msg:\"" + msg + "\",obj:"+obj+"}");
			resp.Write("{code:" + code + ",msg:\"" + msg + "\",obj:"+obj+"}");
			resp.End();
		}

		public static void WriteRet(this HttpResponse resp, string json) {
			Logger.Detail(json);
			resp.Write(json);
			resp.End();
		}

		#endregion

		public static string GetHtmlStrByXpath(string url, string xpath, string cookies, string domain, Encoding encoding, int timeout) {
			string pageSource = GetPageSource(url, cookies, domain, encoding, timeout);

			HtmlAgilityPack.HtmlDocument htmldoc = new HtmlDocument();

			//htmldoc.OptionAutoCloseOnEnd = false;
			//htmldoc.OptionOutputAsXml = true;
			//htmldoc.OptionCheckSyntax = false;
			//htmldoc.OptionFixNestedTags = false;
			//htmldoc.OptionWriteEmptyNodes = true;

			htmldoc.OptionOutputOriginalCase = true;

			htmldoc.LoadHtml(pageSource);

			HtmlNodeCollection hnItems = null;

			StringBuilder sb = new StringBuilder();

			if (!string.IsNullOrEmpty(xpath)) {
				hnItems = htmldoc.DocumentNode.SelectNodes(xpath);

				if (hnItems == null || hnItems.Count == 0) {
					return string.Empty;
				}

				foreach (HtmlNode hn in hnItems) {
					sb.Append(hn.OuterHtml).Append(Environment.NewLine);
				}

				return sb.ToString();
			}
			else {
				htmldoc.DocumentNode.FirstChild.Remove();
				return htmldoc.DocumentNode.InnerHtml;
			}
		}

		public static string GetHtmlStrByXpath(HtmlDocument htmldoc, string xpath) {
			return GetHtmlStrByXpath(htmldoc.DocumentNode, xpath);
		}

		public static string GetHtmlStrByXpath(HtmlNode htmldoc, string xpath) {
			HtmlNodeCollection hnItems = null;

			StringBuilder sb = new StringBuilder();

			if (!string.IsNullOrEmpty(xpath)) {
				hnItems = htmldoc.SelectNodes(xpath);

				if (hnItems == null || hnItems.Count == 0) {
					return string.Empty;
				}

				foreach (HtmlNode hn in hnItems) {
					sb.Append(hn.OuterHtml).Append(Environment.NewLine);
				}

				return sb.ToString();
			}
			else {
				htmldoc.FirstChild.Remove();
				return htmldoc.InnerHtml;
			}
		}

		public static HtmlDocument GetPageHtmlDocument(string url, string cookies, string domain, Encoding encoding, int timeout) {
			string pageSource = GetPageSource(url, cookies, domain, encoding, timeout);

			HtmlAgilityPack.HtmlDocument htmldoc = new HtmlDocument();

			htmldoc.LoadHtml(pageSource);

			return htmldoc;
		}

		public static string GetPageSource(string url, string cookies, string domain, Encoding encoding, int timeout) {
			return GetPageSource(url, FormatCookies(cookies, domain), encoding, timeout);
		}


		public static string GetPageSource(string url, CookieCollection headers, Encoding encoding, int timeout) {
			StreamReader sr = null;
			string strTemp = string.Empty;
			HttpWebRequest WReq = null;
			WebResponse WResp = null;
			try {
				WReq = WebRequest.Create(url) as HttpWebRequest;
				WReq.UserAgent = "Mazila 4.0 (MSIE 6.0 Microsoft)";
				WReq.Timeout = timeout;

				if (headers != null) {
					WReq.CookieContainer = new CookieContainer();

					WReq.CookieContainer.Add(headers);
				}
				//WReq.ServicePoint.ConnectionLimit = 1;


				using (WResp = WReq.GetResponse() as HttpWebResponse) {
					sr = new StreamReader(WResp.GetResponseStream(), encoding);
					strTemp = sr.ReadToEnd();
				}
			}
			catch (WebException ex) {
				Logger.Exception(ex, "GetPageSource");
				//throw ex;
			}
			catch (HttpException ex1) {
				Logger.Exception(ex1, "GetPageSource");
			}
			finally {
				if (sr != null) {
					sr.Close();
				}
			}

			return strTemp;
		}

		public static CookieCollection FormatCookies(string cookies, string domain) {
			if (string.IsNullOrEmpty(cookies)) {
				new CookieCollection();
			}

			CookieCollection nvcHeaders = new CookieCollection();

			if (!string.IsNullOrEmpty(cookies)) {
				string[] hs = Regex.Split(cookies, ";");

				for (int i = 0; i < hs.Length; i++) {
					string[] hss = Regex.Split(hs[i], "=");

					nvcHeaders.Add(new Cookie(hss[0].Trim(), hss[1].Trim(), "/", domain));
				}
			}

			return nvcHeaders;
		}


		/// <summary>
		/// 获得当前用户请求URL
		/// </summary>
		public static string GetRequestUrl() {
			if (HttpContext.Current != null) {
				return HttpContext.Current.Request.Url.ToString();
			}
			return "";
		}

		/// <summary>
		/// 获得真实IP
		/// </summary>
		public static string GetRealIP() {
			try {
				string strTemp;
				HttpRequest requestCurrent = HttpContext.Current.Request;
				if (requestCurrent.ServerVariables["HTTP_X_FORWARDED_FOR"] != "") {
					strTemp = requestCurrent.ServerVariables["REMOTE_ADDR"];
				}
				else {
					strTemp = requestCurrent.ServerVariables["HTTP_X_FORWARDED_FOR"];
				}
				if ((strTemp != null) && (strTemp != "")) {
					return strTemp;
				}
				return requestCurrent.UserHostAddress;
			}
			catch {

			}
			return "";
		}

		public static StringBuilder GetContextString() {
			return GetContextString(HttpContext.Current);
		}

		/// <summary>
		/// 格式化Context信息
		/// </summary>
		/// <param name="context"></param>
		/// <returns></returns>
		public static StringBuilder GetContextString(HttpContext context) {
			if (context == null) {
				return new StringBuilder();
			}

			HttpRequest req = context.Request;
			return new StringBuilder(req.Url + "	" + req.UserHostAddress + "	" + req.HttpMethod + "	" + req.UserAgent);
		}

		/// <summary>
		/// 当前请求的根目录
		/// </summary>
		/// <returns></returns>
		public static string RootPath() {
			int port = HttpContext.Current.Request.Url.Port;
			string host = HttpContext.Current.Request.Url.Host;

			string url = HttpContext.Current.Request.Url.ToString();

			url = Regex.Match(url, @"^.*(?=" + host + ")", RegexOptions.IgnoreCase).ToString();
			url += host;

			if (port != 80) {
				url += ":" + port.ToString();
			}

			url += HttpContext.Current.Request.ApplicationPath;
			if (HttpContext.Current.Request.ApplicationPath != "/") {
				url += "/";
			}

			return url;
		}

		public static string GetIPByHostName(string hostname) {
			if (Dns.GetHostByName(hostname).AddressList.Length > 0) {
				IPEndPoint ipEndPoint = new IPEndPoint(Dns.GetHostByName(hostname).AddressList[0], 0);
				return ipEndPoint.Address.ToString();
			}
			return "";
		}

		public static void DownLoadFile(this HttpResponse resp, string content, string filename) {
			resp.ClearHeaders();
			resp.Clear();
			resp.Expires = 0;
			resp.Buffer = true;
			resp.Charset = "utf-8";
			resp.AddHeader("Accept-Language", "zh-cn");
			resp.AddHeader("content-disposition", "attachment;filename=" + HttpUtility.UrlEncode(filename, Encoding.UTF8));
			resp.ContentType = "Application/octet-stream";
			resp.Write(content);
			resp.End();
		}

		public static string UrlEncodeForUTF8(string input) {
			return HttpUtility.UrlEncode(input, Encoding.UTF8);
		}
		public static string UrlDecodeForUTF8(string input) {
			return HttpUtility.UrlDecode(input, Encoding.UTF8);
		}

		public static string GetPhotoImgFromUrl(string url) {
			string Value = "<img src=\"{0}\" width=\"{1}\" height=\"{2}\" />";
			WebResponse response = null;
			Stream stream = null;
			try {
				HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
				response = request.GetResponse();
				stream = response.GetResponseStream();
				if (!response.ContentType.ToLower().StartsWith("text/")) {
					Image i = Image.FromStream(stream);
					if (i.Height > i.Width) {
						return string.Format(Value, url, (235 * i.Width / i.Height) + "", "235");
					}
					else {
						return string.Format(Value, url, "235", (235 * i.Height / i.Width) + "");
					}
				}
			}
			catch {

			}
			return string.Format(Value, url, "235", "235");
		}

		public static Image GetPhotoImageFromUrl(string url) {
			//string Value = "<img src=\"{0}\" width=\"{1}\" height=\"{2}\" />";
			WebResponse response = null;
			Stream stream = null;
			try {
				HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
				response = request.GetResponse();
				stream = response.GetResponseStream();
				if (!response.ContentType.ToLower().StartsWith("text/")) {
					Image i = Image.FromStream(stream);
					return i;
				}
			}
			catch {

			}
			return null;
		}

		/// <summary>    
		/// 在图片上添加图片水印    
		/// </summary>   
		/// <param name="path">原服务器上的图片路径</param>    
		/// <param name="syPicPath">水印图片的路径</param>    
		/// <param name="waterPicPath">生成的水印图片存放路径</param>    
		public static void AddWaterPic(string path, string syPicPath, string waterPicPath) {
			System.Drawing.Image image = System.Drawing.Image.FromFile(path);
			System.Drawing.Image waterImage = System.Drawing.Image.FromFile(syPicPath);
			System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage(image);
			graphic.DrawImage(waterImage, new System.Drawing.Rectangle(image.Width - waterImage.Width, image.Height - waterImage.Height, waterImage.Width, waterImage.Height), 0, 0, waterImage.Width, waterImage.Height, System.Drawing.GraphicsUnit.Pixel);
			graphic.Dispose();
			image.Save(waterPicPath);
			image.Dispose();
		}

		/// <summary> 
		/// 在图片上加入图片版权信息 
		/// </summary> 
		/// <param name="strFileName">输入图片(绝对路径)</param> 		
		/// <param name="strCopyRightFile">水印图片(绝对路径)</param> 
		/// /// <param name="strOutfileName">输出图片(绝对路径)</param> 
		/// <param name="StrPlace">水印位置</param> 
		public static void AddWaterPic(string strFileName, string strCopyRightFile, string strOutfileName, string StrPlace) {
			System.Drawing.Image MyImage = System.Drawing.Image.FromFile(strFileName);
			System.Drawing.Image CopyMyImage = System.Drawing.Image.FromFile(strCopyRightFile);
			System.Drawing.Bitmap OutPut = new System.Drawing.Bitmap(MyImage);
			System.Drawing.Graphics GImage = System.Drawing.Graphics.FromImage(OutPut);

			int IntX = 0;
			int IntY = 0;
			if (StrPlace == "1")   // 在左上 
            {
				IntX = 0;
				IntY = 0;
			}
			else if (StrPlace == "2")  // 在正上 
            {
				IntX = (MyImage.Width - CopyMyImage.Width) / 2;
				IntY = 0;
			}
			else if (StrPlace == "3")  // 在右上 
            {
				IntX = MyImage.Width - CopyMyImage.Width;
				IntY = 0;
			}
			else if (StrPlace == "4")  // 在正左 
            {
				IntX = 0;
				IntY = (MyImage.Height - CopyMyImage.Height) / 2;
			}
			else if (StrPlace == "5")  // 在中间 
            {
				IntX = (MyImage.Width - CopyMyImage.Width) / 2;
				IntY = (MyImage.Height - CopyMyImage.Height) / 2;
			}
			else if (StrPlace == "6")  // 在正右 
            {
				IntX = MyImage.Width - CopyMyImage.Width;
				IntY = (MyImage.Height - CopyMyImage.Height) / 2;
			}
			else if (StrPlace == "7")  // 在左下 
            {
				IntX = 0;
				IntY = MyImage.Height - CopyMyImage.Height;
			}
			else if (StrPlace == "8")  // 在正下 
            {
				IntX = (MyImage.Width - CopyMyImage.Width) / 2;
				IntY = MyImage.Height - CopyMyImage.Height;
			}
			else if (StrPlace == "9")  // 在右下 
            {
				IntX = MyImage.Width - CopyMyImage.Width;
				IntY = MyImage.Height - CopyMyImage.Height;
			}
			else {
				IntX = MyImage.Width - CopyMyImage.Width - 10;
				IntY = MyImage.Height - CopyMyImage.Height - 10;
			}

			// 画出水印的位置 
			GImage.DrawImage(CopyMyImage, IntX, IntY, CopyMyImage.Width, CopyMyImage.Height);
			string strExtend = strFileName.Substring(strFileName.LastIndexOf(".") + 1).ToLower();

			switch (strExtend) {
				case "bmp":
					OutPut.Save(strOutfileName, System.Drawing.Imaging.ImageFormat.Bmp);
					break;
				case "jpg":
					OutPut.Save(strOutfileName, System.Drawing.Imaging.ImageFormat.Jpeg);
					break;
				case "gif":
					OutPut.Save(strOutfileName, System.Drawing.Imaging.ImageFormat.Gif);
					break;
				case "icon":
					OutPut.Save(strOutfileName, System.Drawing.Imaging.ImageFormat.Icon);
					break;
				case "png":
					OutPut.Save(strOutfileName, System.Drawing.Imaging.ImageFormat.Png);
					break;
				case "tif":
					OutPut.Save(strOutfileName, System.Drawing.Imaging.ImageFormat.Tiff);
					break;
				default:
					OutPut.Save(strOutfileName, System.Drawing.Imaging.ImageFormat.Jpeg);
					break;
			}

			GImage.Dispose();
			OutPut.Dispose();
			MyImage.Dispose();
			CopyMyImage.Dispose();
		}




		#region 将文件转换成流
		/// <summary>
		/// 将文件转换成流
		/// </summary>
		/// <param name="fileName">文件全路径</param>
		/// <returns></returns>
		private static byte[] SetImageToByteArray(string fileName) {
			byte[] image = null;
			try {
				FileStream fs = new FileStream(fileName, FileMode.Open);
				FileInfo fileInfo = new FileInfo(fileName);
				//fileSize = Convert.ToDecimal(fileInfo.Length / 1024).ToString("f2") + " K";
				int streamLength = (int)fs.Length;
				image = new byte[streamLength];
				fs.Read(image, 0, streamLength);
				fs.Close();
				return image;
			}
			catch {
				return image;
			}
		}
		#endregion

		#region 将byte转换成MemoryStream类型
		/// <summary>
		/// 将byte转换成MemoryStream类型
		/// </summary>
		/// <param name="mybyte">byte[]变量</param>
		/// <returns></returns>
		private static MemoryStream ByteToStream(byte[] mybyte) {
			MemoryStream mymemorystream = new MemoryStream(mybyte, 0, mybyte.Length);
			return mymemorystream;
		}
		#endregion

		#region 将byte转换成Image文件
		/// <summary>
		/// 将byte转换成Image文件
		/// </summary>
		/// <param name="mybyte">byte[]变量</param>
		/// <returns></returns>
		private static System.Drawing.Image SetByteToImage(byte[] mybyte) {
			System.Drawing.Image image;
			MemoryStream mymemorystream = new MemoryStream(mybyte, 0, mybyte.Length);
			image = System.Drawing.Image.FromStream(mymemorystream);
			return image;
		}
		#endregion

		public static bool DrawWords(string sourcePicture, string waterWords, float alpha, ImagePosition position, bool fRewrite) {
			string newPicture = sourcePicture;
			if (!fRewrite) {
				string fileExtension = System.IO.Path.GetExtension(sourcePicture).ToLower();
				newPicture = sourcePicture.Replace(System.IO.Path.GetExtension(sourcePicture), "") + "_0607" + fileExtension;
			}
			return DrawWords(sourcePicture, waterWords, alpha, position, newPicture);
		}

		/// <summary>
		/// 在图片上添加透明水印文字
		/// </summary>
		/// <param name="sourcePicture">原来图片地址(路径+文件名)</param>
		/// <param name="waterWords">需要添加到图片上的文字</param>
		/// <param name="alpha">透明度(0.1~1.0之间)</param>
		/// <param name="position">文字显示的位置</param>
		/// <param name="fRewrite">是否覆盖原图片(如果不覆盖，那么将在同目录下生成一个文件名带0607的文件)</param>
		/// <returns></returns>
		public static bool DrawWords(string sourcePicture, string waterWords, float alpha, ImagePosition position, string newPicture) {
			string _ErrMsg = string.Empty;
			if (!System.IO.File.Exists(sourcePicture)) {
				_ErrMsg = "文件不存在！";
				return false;
			}
			string fileExtension = System.IO.Path.GetExtension(sourcePicture).ToLower();
			if (fileExtension != ".gif" && fileExtension != ".jpg" && fileExtension != ".png" && fileExtension != ".bmp") {
				_ErrMsg = "不是图片文件！";
				return false;
			}

			Image imgPhoto = null;
			Bitmap bmPhoto = null;
			Graphics grPhoto = null;
			try {
				//创建一个图片对象用来装载要被添加水印的图片
				imgPhoto = Image.FromStream(ByteToStream(SetImageToByteArray(sourcePicture)));

				//获取图片的宽和高
				int phWidth = imgPhoto.Width;
				int phHeight = imgPhoto.Height;

				//建立一个bitmap，和我们需要加水印的图片一样大小
				bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

				//SetResolution：设置此 Bitmap 的分辨率
				//这里直接将我们需要添加水印的图片的分辨率赋给了bitmap
				bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

				//Graphics：封装一个 GDI+ 绘图图面。
				grPhoto = Graphics.FromImage(bmPhoto);

				//设置图形的品质
				grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

				//将我们要添加水印的图片按照原始大小描绘（复制）到图形中
				grPhoto.DrawImage(
				 imgPhoto,                                           //   要添加水印的图片
				 new Rectangle(0, 0, phWidth, phHeight), //  根据要添加的水印图片的宽和高
				 0,                                                     //  X方向从0点开始描绘
				 0,                                                     // Y方向 
				 phWidth,                                            //  X方向描绘长度
				 phHeight,                                           //  Y方向描绘长度
				 GraphicsUnit.Pixel);                              // 描绘的单位，这里用的是像素

				//根据图片的大小我们来确定添加上去的文字的大小
				//在这里我们定义一个数组来确定
				int[] sizes = new int[] { 48, 36, 28, 24, 16, 14, 12, 10 };
				//int[] sizes = new int[] { 16, 14, 12, 10 ,8 ,6 ,4 ,2};

				//字体
				Font crFont = null;
				//矩形的宽度和高度，SizeF有三个属性，分别为Height高，width宽，IsEmpty是否为空
				SizeF crSize = new SizeF();

				//利用一个循环语句来选择我们要添加文字的型号
				//直到它的长度比图片的宽度小
				for (int i = 0; i < sizes.Length; i++) {
					crFont = new Font("arial", sizes[i], FontStyle.Bold);

					//测量用指定的 Font 对象绘制并用指定的 StringFormat 对象格式化的指定字符串。
					crSize = grPhoto.MeasureString(waterWords, crFont);

					// ushort 关键字表示一种整数数据类型
					if ((ushort)crSize.Width < (ushort)phWidth * 0.5)
						break;
				}

				//截边5%的距离，定义文字显示(由于不同的图片显示的高和宽不同，所以按百分比截取)
				int yPixlesFromBottom = (int)(phHeight * .05);

				//定义在图片上文字的位置
				float wmHeight = crSize.Height;
				float wmWidth = crSize.Width;

				float xPosOfWm;
				float yPosOfWm;

				//设置水印的位置
				switch (position) {
					case ImagePosition.BottomMiddle:
						xPosOfWm = phWidth / 2;
						yPosOfWm = phHeight - wmHeight - 10;
						break;
					case ImagePosition.Center:
						xPosOfWm = phWidth / 2;
						yPosOfWm = phHeight / 2;
						break;
					case ImagePosition.LeftBottom:
						xPosOfWm = wmWidth;
						yPosOfWm = phHeight - wmHeight - 10;
						break;
					case ImagePosition.LeftTop:
						xPosOfWm = wmWidth / 2;
						yPosOfWm = wmHeight / 2;
						break;
					case ImagePosition.RightTop:
						xPosOfWm = phWidth - wmWidth - 10;
						yPosOfWm = wmHeight;
						break;
					case ImagePosition.RigthBottom:
						xPosOfWm = phWidth - wmWidth - 10;
						yPosOfWm = phHeight - wmHeight - 10;
						break;
					case ImagePosition.TopMiddle:
						xPosOfWm = phWidth / 2;
						yPosOfWm = wmHeight;
						break;
					default:
						xPosOfWm = wmWidth;
						yPosOfWm = phHeight - wmHeight - 10;
						break;
				}
				//封装文本布局信息（如对齐、文字方向和 Tab 停靠位），显示操作（如省略号插入和国家标准 (National) 数字替换）和 OpenType 功能。
				StringFormat StrFormat = new StringFormat();

				//定义需要印的文字居中对齐
				StrFormat.Alignment = StringAlignment.Center;

				//SolidBrush:定义单色画笔。画笔用于填充图形形状，如矩形、椭圆、扇形、多边形和封闭路径。
				//这个画笔为描绘阴影的画笔，呈灰色
				int m_alpha = Convert.ToInt32(256 * alpha);
				SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(m_alpha, 255, 255, 255));

				//描绘文字信息，这个图层向右和向下偏移一个像素，表示阴影效果
				//DrawString 在指定矩形并且用指定的 Brush 和 Font 对象绘制指定的文本字符串。
				grPhoto.DrawString(waterWords,                                    //string of text
										   crFont,                                         //font
										   semiTransBrush2,                            //Brush
										   new PointF(xPosOfWm + 1, yPosOfWm + 1),  //Position
										   StrFormat);

				//从四个 ARGB 分量（alpha、红色、绿色和蓝色）值创建 Color 结构，这里设置透明度为153
				//这个画笔为描绘正式文字的笔刷，呈白色
				SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 120, 0));

				//第二次绘制这个图形，建立在第一次描绘的基础上
				grPhoto.DrawString(waterWords,                 //string of text
										   crFont,                                   //font
										   semiTransBrush,                           //Brush
										   new PointF(xPosOfWm, yPosOfWm),  //Position
										   StrFormat);

				//imgPhoto是我们建立的用来装载最终图形的Image对象
				//bmPhoto是我们用来制作图形的容器，为Bitmap对象
				imgPhoto = bmPhoto;
				//释放资源，将定义的Graphics实例grPhoto释放，grPhoto功德圆满
				//grPhoto.Dispose();

				//将grPhoto保存

				imgPhoto.Save(newPicture);

				//imgPhoto.Dispose();
				return true;
			}
			catch (Exception ex) {
				_ErrMsg = ex.Message;
				return false;
			}
			finally {
				if (imgPhoto != null)
					imgPhoto.Dispose();
				if (bmPhoto != null)
					bmPhoto.Dispose();
				if (grPhoto != null)
					grPhoto.Dispose();
			}


		}

		/// <summary>
		/// 生成缩略图
		/// </summary>
		/// <param name="originalImagePath">源图路径（物理路径）</param>
		/// <param name="thumbnailPath">缩略图路径（物理路径）</param>
		/// <param name="width">缩略图宽度</param>
		/// <param name="height">缩略图高度</param>
		/// <param name="mode">生成缩略图的方式</param>    
		public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode) {
			Image originalImage = Image.FromFile(originalImagePath);

			int towidth = width;
			int toheight = height;

			int x = 0;
			int y = 0;
			int ow = originalImage.Width;
			int oh = originalImage.Height;

			switch (mode) {
				case "HW"://指定高宽缩放（可能变形）                
					break;
				case "W"://指定宽，高按比例                    
					toheight = originalImage.Height * width / originalImage.Width;
					break;
				case "H"://指定高，宽按比例
					towidth = originalImage.Width * height / originalImage.Height;
					break;
				case "Cut"://指定高宽裁减（不变形）                
					if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight) {
						oh = originalImage.Height;
						ow = originalImage.Height * towidth / toheight;
						y = 0;
						x = (originalImage.Width - ow) / 2;
					}
					else {
						ow = originalImage.Width;
						oh = originalImage.Width * height / towidth;
						x = 0;
						y = (originalImage.Height - oh) / 2;
					}
					break;
				default:
					break;
			}

			//新建一个bmp图片
			Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

			//新建一个画板
			Graphics g = System.Drawing.Graphics.FromImage(bitmap);

			//设置高质量插值法
			g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

			//设置高质量,低速度呈现平滑程度
			g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

			//清空画布并以透明背景色填充
			g.Clear(Color.Transparent);

			//在指定位置并且按指定大小绘制原图片的指定部分
			g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
				new Rectangle(x, y, ow, oh),
				GraphicsUnit.Pixel);

			try {
				//以jpg格式保存缩略图
				bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
			}
			catch (System.Exception e) {
				throw e;
			}
			finally {
				originalImage.Dispose();
				bitmap.Dispose();
				g.Dispose();
			}
		}

		
		public static bool IsNullableType(Type t) {
			return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
		}

		public static bool HasDefaultConstructor(Type t) {

			if (t.IsValueType)
				return true;

			return (t.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null) != null);
		}

		public static Type GetObjectType(object v) {
			return (v != null) ? v.GetType() : null;
		}

		#region 字符串相关

		public static string FormatWith(this string format, IFormatProvider provider, params object[] args) {
			return string.Format(provider, format, args);
		}

		public static string NullEmptyString(string s) {
			return (string.IsNullOrEmpty(s)) ? null : s;
		}



		/// <summary>
		/// 截取字符串 拓展方法
		/// </summary>
		/// <param name="Str">原字符串</param>
		/// <param name="Num">要截取的长度</param>
		/// <returns>截取后的字符串</returns>
		public static int Length(this string Str) {
			int n = 0;
			foreach (char ch in Str) {
				n += System.Text.Encoding.Default.GetByteCount(ch.ToString());
			}
			return n;
		}

		/// <summary>
		/// 截取字符串 拓展方法
		/// </summary>
		/// <param name="Str">原字符串</param>
		/// <param name="Num">要截取的长度</param>
		/// <returns>截取后的字符串</returns>
		public static string SubString(this string Str, int Num) {
			if (Str == null || Str == "")
				return "";
			string outstr = "";
			int n = 0;
			foreach (char ch in Str) {
				n += System.Text.Encoding.Default.GetByteCount(ch.ToString());
				if (n > Num)
					break;
				else
					outstr += ch;
			}
			return outstr;
		}

		#endregion
		
	}
}
